﻿using System;
using System.Collections;
using System.Globalization;
using System.Reflection;
using System.Text;

namespace DeJson
{
	// Token: 0x02000044 RID: 68
	public class Serializer
	{
		// Token: 0x06000224 RID: 548 RVA: 0x00011AA0 File Offset: 0x0000FCA0
		public static string Serialize(object obj, bool includeTypeInfoForDerivedTypes = false, bool prettyPrint = false)
		{
			Serializer serializer = new Serializer(includeTypeInfoForDerivedTypes, prettyPrint);
			serializer.SerializeValue(obj);
			return serializer.GetJson();
		}

		// Token: 0x06000225 RID: 549 RVA: 0x00011AC8 File Offset: 0x0000FCC8
		private Serializer(bool includeTypeInfoForDerivedTypes, bool prettyPrint)
		{
			this.m_builder = new StringBuilder();
			this.m_includeTypeInfoForDerivedTypes = includeTypeInfoForDerivedTypes;
			this.m_prettyPrint = prettyPrint;
			this.m_prefix = "";
		}

		// Token: 0x06000226 RID: 550 RVA: 0x00011AF8 File Offset: 0x0000FCF8
		private string GetJson()
		{
			return this.m_builder.ToString();
		}

		// Token: 0x06000227 RID: 551 RVA: 0x00011B18 File Offset: 0x0000FD18
		private void Indent()
		{
			bool prettyPrint = this.m_prettyPrint;
			if (prettyPrint)
			{
				this.m_prefix += "  ";
			}
		}

		// Token: 0x06000228 RID: 552 RVA: 0x00011B48 File Offset: 0x0000FD48
		private void Outdent()
		{
			bool prettyPrint = this.m_prettyPrint;
			if (prettyPrint)
			{
				this.m_prefix = this.m_prefix.Substring(2);
			}
		}

		// Token: 0x06000229 RID: 553 RVA: 0x00011B74 File Offset: 0x0000FD74
		private void AddIndent()
		{
			bool prettyPrint = this.m_prettyPrint;
			if (prettyPrint)
			{
				this.m_builder.Append(this.m_prefix);
			}
		}

		// Token: 0x0600022A RID: 554 RVA: 0x00011BA0 File Offset: 0x0000FDA0
		private void AddLine()
		{
			bool prettyPrint = this.m_prettyPrint;
			if (prettyPrint)
			{
				this.m_builder.Append("\n");
			}
		}

		// Token: 0x0600022B RID: 555 RVA: 0x00011BCC File Offset: 0x0000FDCC
		private void AddSpace()
		{
			bool prettyPrint = this.m_prettyPrint;
			if (prettyPrint)
			{
				this.m_builder.Append(" ");
			}
		}

		// Token: 0x0600022C RID: 556 RVA: 0x00011BF8 File Offset: 0x0000FDF8
		private void SerializeValue(object obj)
		{
			bool flag = obj == null;
			if (flag)
			{
				this.m_builder.Append("undefined");
			}
			else
			{
				Type type = obj.GetType();
				bool isArray = type.IsArray;
				if (isArray)
				{
					this.SerializeArray(obj);
				}
				else
				{
					bool flag2 = type == typeof(string);
					if (flag2)
					{
						this.SerializeString(obj as string);
					}
					else
					{
						bool flag3 = type == typeof(char);
						if (flag3)
						{
							this.SerializeString(obj.ToString());
						}
						else
						{
							bool flag4 = type == typeof(bool);
							if (flag4)
							{
								this.m_builder.Append(((bool)obj) ? "true" : "false");
							}
							else
							{
								bool flag5 = type == typeof(bool);
								if (flag5)
								{
									this.m_builder.Append(((bool)obj) ? "true" : "false");
									this.m_builder.Append(Convert.ChangeType(obj, typeof(string)));
								}
								else
								{
									bool flag6 = type == typeof(int);
									if (flag6)
									{
										this.m_builder.Append(obj);
									}
									else
									{
										bool flag7 = type == typeof(byte);
										if (flag7)
										{
											this.m_builder.Append(obj);
										}
										else
										{
											bool flag8 = type == typeof(sbyte);
											if (flag8)
											{
												this.m_builder.Append(obj);
											}
											else
											{
												bool flag9 = type == typeof(short);
												if (flag9)
												{
													this.m_builder.Append(obj);
												}
												else
												{
													bool flag10 = type == typeof(ushort);
													if (flag10)
													{
														this.m_builder.Append(obj);
													}
													else
													{
														bool flag11 = type == typeof(int);
														if (flag11)
														{
															this.m_builder.Append(obj);
														}
														else
														{
															bool flag12 = type == typeof(uint);
															if (flag12)
															{
																this.m_builder.Append(obj);
															}
															else
															{
																bool flag13 = type == typeof(long);
																if (flag13)
																{
																	this.m_builder.Append(obj);
																}
																else
																{
																	bool flag14 = type == typeof(ulong);
																	if (flag14)
																	{
																		this.m_builder.Append(obj);
																	}
																	else
																	{
																		bool flag15 = type == typeof(float);
																		if (flag15)
																		{
																			this.m_builder.Append(((float)obj).ToString("R", CultureInfo.InvariantCulture));
																		}
																		else
																		{
																			bool flag16 = type == typeof(double);
																			if (flag16)
																			{
																				this.m_builder.Append(((double)obj).ToString("R", CultureInfo.InvariantCulture));
																			}
																			else
																			{
																				bool flag17 = type == typeof(float);
																				if (flag17)
																				{
																					this.m_builder.Append(((float)obj).ToString("R", CultureInfo.InvariantCulture));
																				}
																				else
																				{
																					bool flag18 = type == typeof(double);
																					if (flag18)
																					{
																						this.m_builder.Append(((double)obj).ToString("R", CultureInfo.InvariantCulture));
																					}
																					else
																					{
																						bool isValueType = type.IsValueType;
																						if (isValueType)
																						{
																							this.SerializeObject(obj);
																						}
																						else
																						{
																							bool isClass = type.IsClass;
																							if (!isClass)
																							{
																								throw new InvalidOperationException("unsupport type: " + type.Name);
																							}
																							this.SerializeObject(obj);
																						}
																					}
																				}
																			}
																		}
																	}
																}
															}
														}
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}

		// Token: 0x0600022D RID: 557 RVA: 0x00011FC0 File Offset: 0x000101C0
		private void SerializeArray(object obj)
		{
			this.m_builder.Append("[");
			this.AddLine();
			this.Indent();
			Array array = obj as Array;
			bool flag = true;
			foreach (object obj2 in array)
			{
				bool flag2 = !flag;
				if (flag2)
				{
					this.m_builder.Append(",");
					this.AddLine();
				}
				this.AddIndent();
				this.SerializeValue(obj2);
				flag = false;
			}
			this.AddLine();
			this.Outdent();
			this.AddIndent();
			this.m_builder.Append("]");
		}

		// Token: 0x0600022E RID: 558 RVA: 0x00012094 File Offset: 0x00010294
		private void SerializeDictionary(IDictionary obj)
		{
			bool flag = true;
			foreach (object obj2 in obj.Keys)
			{
				bool flag2 = !flag;
				if (flag2)
				{
					this.m_builder.Append(',');
					this.AddLine();
				}
				this.AddIndent();
				this.SerializeString(obj2.ToString());
				this.m_builder.Append(':');
				this.AddSpace();
				this.SerializeValue(obj[obj2]);
				flag = false;
			}
		}

		// Token: 0x0600022F RID: 559 RVA: 0x00012144 File Offset: 0x00010344
		private void SerializeObject(object obj)
		{
			this.m_builder.Append("{");
			this.AddLine();
			this.Indent();
			bool flag = true;
			bool includeTypeInfoForDerivedTypes = this.m_includeTypeInfoForDerivedTypes;
			if (includeTypeInfoForDerivedTypes)
			{
				Type type = obj.GetType();
				Type baseType = type.BaseType;
				bool flag2 = baseType != null && baseType != typeof(object);
				if (flag2)
				{
					this.AddIndent();
					this.SerializeString("$dotNetType");
					this.m_builder.Append(":");
					this.AddSpace();
					this.SerializeString(type.FullName);
				}
			}
			IDictionary obj2;
			bool flag3 = (obj2 = (obj as IDictionary)) != null;
			if (flag3)
			{
				this.SerializeDictionary(obj2);
			}
			else
			{
				FieldInfo[] fields = obj.GetType().GetFields();
				foreach (FieldInfo fieldInfo in fields)
				{
					bool isStatic = fieldInfo.IsStatic;
					if (!isStatic)
					{
						object value = fieldInfo.GetValue(obj);
						bool flag4 = value != null;
						if (flag4)
						{
							bool flag5 = !flag;
							if (flag5)
							{
								this.m_builder.Append(",");
								this.AddLine();
							}
							this.AddIndent();
							this.SerializeString(fieldInfo.Name);
							this.m_builder.Append(":");
							this.AddSpace();
							this.SerializeValue(value);
							flag = false;
						}
					}
				}
			}
			this.AddLine();
			this.Outdent();
			this.AddIndent();
			this.m_builder.Append("}");
		}

		// Token: 0x06000230 RID: 560 RVA: 0x000122E8 File Offset: 0x000104E8
		private void SerializeString(string str)
		{
			this.m_builder.Append('"');
			char[] array = str.ToCharArray();
			char[] array2 = array;
			int i = 0;
			while (i < array2.Length)
			{
				char c = array2[i];
				char c2 = c;
				switch (c2)
				{
				case '\b':
					this.m_builder.Append("\\b");
					break;
				case '\t':
					this.m_builder.Append("\\t");
					break;
				case '\n':
					this.m_builder.Append("\\n");
					break;
				case '\v':
					goto IL_F2;
				case '\f':
					this.m_builder.Append("\\f");
					break;
				case '\r':
					this.m_builder.Append("\\r");
					break;
				default:
					if (c2 != '"')
					{
						if (c2 != '\\')
						{
							goto IL_F2;
						}
						this.m_builder.Append("\\\\");
					}
					else
					{
						this.m_builder.Append("\\\"");
					}
					break;
				}
				IL_150:
				i++;
				continue;
				IL_F2:
				int num = Convert.ToInt32(c);
				bool flag = num >= 32 && num <= 126;
				if (flag)
				{
					this.m_builder.Append(c);
				}
				else
				{
					this.m_builder.Append("\\u");
					this.m_builder.Append(num.ToString("x4"));
				}
				goto IL_150;
			}
			this.m_builder.Append('"');
		}

		// Token: 0x04000209 RID: 521
		private StringBuilder m_builder;

		// Token: 0x0400020A RID: 522
		private bool m_includeTypeInfoForDerivedTypes;

		// Token: 0x0400020B RID: 523
		private bool m_prettyPrint;

		// Token: 0x0400020C RID: 524
		private string m_prefix;
	}
}
